package org.nature.framework.listener;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.sql.DataSource;

import org.nature.framework.auth.AuthFilter;
import org.nature.framework.cache.CacheManager;
import org.nature.framework.cache.NatureCacheManager;
import org.nature.framework.db.DataSourceFactory;
import org.nature.framework.helper.ConfigHelper;
import org.nature.framework.helper.CtrlHelper;
import org.nature.framework.helper.I18NHelper;
import org.nature.framework.helper.InterceptorHelper;
import org.nature.framework.helper.ServiceHelper;
import org.nature.framework.helper.TableAutoCreateHelper;
import org.nature.framework.helper.TableBeanHelper;
import org.nature.framework.helper.ValidatorHelper;
import org.nature.framework.plugin.PluginHelper;
import org.nature.framework.quartz.QuartzJobHelper;
import org.nature.framework.restful.RestfulTransfer;
import org.nature.framework.util.FilterUtil;
import org.nature.framework.util.StringUtil;
import org.nature.framework.ws.WsHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.druid.pool.DruidDataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;

@WebListener
public class NatureListener implements ServletContextListener {
	private static Logger LOGGER = LoggerFactory.getLogger(NatureListener.class);

	public void contextDestroyed(ServletContextEvent sce)  {
		QuartzJobHelper.clear();
		WsHelper.clear();
		CtrlHelper.clear();
		ServiceHelper.clear();
		ValidatorHelper.clear();
		InterceptorHelper.clear();
		TableBeanHelper.clear();
		I18NHelper.clear(); 
		RestfulTransfer.clear();
		if (StringUtil.isNotBank(ConfigHelper.getJdbcDriver(ConfigHelper.getDb()[0]))) {
			Map<String, DataSource> dataSourceMap = DataSourceFactory.getDataSourceMap();
	    	Set<Entry<String, DataSource>> entrySet = dataSourceMap.entrySet();
	    	for (Entry<String, DataSource> entry : entrySet) {
	    		DataSource value = entry.getValue();
	    		if(value instanceof DruidDataSource){
	    			DruidDataSource dds = (DruidDataSource) value;
	    			dds.unregisterMbean();
	    			dds.close();
	    		}else if (value instanceof ComboPooledDataSource) {
	    			ComboPooledDataSource cpds = (ComboPooledDataSource) value;
	    			cpds.close(); 
				}
			} 
		}
    	if (StringUtil.isNotBank(ConfigHelper.getCacheManager())) {
			 NatureCacheManager cacheManager = CacheManager.getCacheManager();
			 if (cacheManager!=null) {
				 cacheManager.destroy(); 
			}
		}
    	PluginHelper.stopPlugins(sce);  
    }

    public void contextInitialized(ServletContextEvent sce)  { 
    	init();
    	FilterUtil.initExcludes();
    	if (ConfigHelper.getAuth()) {
    		sce.getServletContext().addFilter("authFilter", AuthFilter.class).addMappingForUrlPatterns(null, false, "/*");
		}
    	PluginHelper.startPlugins(sce);
    }
    
    private void init(){
    	I18NHelper.initI18nMap();
		TableBeanHelper.initTableBeans();
		InterceptorHelper.initInterceptor();
		ValidatorHelper.initValidator();
		ServiceHelper.initServices(); 
		CtrlHelper.initCtrls();
		RestfulTransfer.initRestBeans();
		WsHelper.initWs();
		QuartzJobHelper.initQuartzJob();
		TableAutoCreateHelper.initDbTable();
		LOGGER.debug("nature-framework init finished");
    }
}
